package com.local.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.local.dao.mapers.LocalCarTypeMapper;
import com.local.dao.mapers.LocalChargeBytimeMapper;
import com.local.manager.cfgManager.CloudConfigManager;
import com.local.model.LocalChargeBytime;
import com.local.model.LocalChargeBytimeExample;
import com.local.model.LocalWeekSection;
import com.local.model.LocalWeekSectionExample;
import com.local.page.LocalChargeByTimePage;
import com.local.service.face.LocalChargeByTimeService;
import com.local.service.face.LocalWeekSectionService;
import com.qianhai.common.dao.face.BaseMapper;
import com.qianhai.common.exception.BaseException;
import com.qianhai.common.service.impl.BaseServiceImpl;
import com.qianhai.common.utils.Tools;
import com.qianhai.common.utils.UUIDGenerateUtil;

@Service
public class LocalChargeByTimeServiceImpl extends
		BaseServiceImpl<LocalChargeBytimeExample, LocalChargeBytime, String>
		implements LocalChargeByTimeService
{
	@Autowired
	private LocalChargeBytimeMapper localChargeBytimeMapper;
	
	@Autowired
	private LocalCarTypeMapper localCarTypeMapper;
	
	@Autowired
	private LocalWeekSectionService localWeekSectionService;
	
	@Override
	public List<LocalChargeBytime> queryChargeByPage(
			LocalChargeByTimePage<LocalChargeBytime> page)
	{
		Integer recordCount = localChargeBytimeMapper.countAllByPage(page);
		page.setTotalRecords(recordCount);
		List<LocalChargeBytime> list = localChargeBytimeMapper
				.queryByPage(page);
		for (int i = 0; i < list.size(); i++)
		{
			LocalChargeBytime lb = list.get(i);
			lb.setCartypeName(localCarTypeMapper.selectCarNameByUuid(
					lb.getCarType()).getCartypeName());
			LocalWeekSection lws = localWeekSectionService
					.loadAllWeekSectionByChargUuid(lb.getChargeBytimeUuid());
			lb.setType(lws.getType());
			lb.setSection(lws.getSection());
			lb.setSectionStartTime(lws.getSectionStartTime());
			lb.setSectionEndTime(lws.getSectionEndTime());
		}
		page.setData(list);
		return list;
	}
	
	@Override
	public BaseMapper<LocalChargeBytimeExample, LocalChargeBytime, String> getMapper()
	{
		// TODO Auto-generated method stub
		return localChargeBytimeMapper;
	}
	
	@Override
	public String saveOrUpdateParkwellMember(LocalChargeBytime localChargeBytime)
	{
		try
		{
			if (Tools.isEmpty(localChargeBytime.getChargeBytimeUuid()))
			{
				if (Tools.isEmpty(localChargeBytime.getFreeTime()))
				{
					throw new BaseException("50000-00001-00051");
				}
				if (Tools.isEmpty(localChargeBytime.getFreeTimeCharge()))
				{
					throw new BaseException("50000-00001-00052");
				}
				if (Tools.isEmpty(localChargeBytime.getBaseTime()))
				{
					throw new BaseException("50000-00001-00053");
				}
				if (Tools.isEmpty(localChargeBytime.getBaseTimeCharge()))
				{
					throw new BaseException("50000-00001-00054");
				}
				if (Tools.isEmpty(localChargeBytime.getSupassTime()))
				{
					throw new BaseException("50000-00001-00055");
				}
				if (Tools.isEmpty(localChargeBytime.getAccountTimeCharge()))
				{
					throw new BaseException("50000-00001-00056");
				}
				if (Tools.isEmpty(localChargeBytime.getAttr2()))
				{
					throw new BaseException("50000-00001-00063");
				}
				if (Tools.isEmpty(localChargeBytime.getMaxCharge())
						&& Tools.isEmpty(localChargeBytime.getAccountTime()))
				{
					localChargeBytime.setAccountTime(null);
					localChargeBytime.setMaxCharge(null);
				}
				if (Tools.isEmpty(localChargeBytime.getSection())
						|| Tools.isEmpty(localChargeBytime.getType()))
				{
					localChargeBytime.setSection("2");
					localChargeBytime.setType("3");
				}
				if (localChargeBytime.getSection().equalsIgnoreCase("1"))
				{
					if (Tools.isEmpty(localChargeBytime.getSectionStartTime()))
					{
						throw new BaseException("50000-00001-00058");
					}
					if (Tools.isEmpty(localChargeBytime.getSectionEndTime()))
					{
						throw new BaseException("50000-00001-00059");
					}
				}
				if (Tools.isEmpty(localChargeBytime.getStatus()))
				{
					localChargeBytime.setStatus(1);
				}
				localChargeBytime.setChargeBytimeUuid(UUIDGenerateUtil
						.generate());
				localChargeBytimeMapper.insert(localChargeBytime);
				
				localWeekSectionService.saveLocalWeekSection(localChargeBytime);
			} else
			{
				if (Tools.isEmpty(localChargeBytime.getFreeTime()))
				{
					throw new BaseException("50000-00001-00051");
				}
				if (Tools.isEmpty(localChargeBytime.getFreeTimeCharge()))
				{
					throw new BaseException("50000-00001-00052");
				}
				if (Tools.isEmpty(localChargeBytime.getBaseTime()))
				{
					throw new BaseException("50000-00001-00053");
				}
				if (Tools.isEmpty(localChargeBytime.getBaseTimeCharge()))
				{
					throw new BaseException("50000-00001-00054");
				}
				if (Tools.isEmpty(localChargeBytime.getSupassTime()))
				{
					throw new BaseException("50000-00001-00055");
				}
				if (Tools.isEmpty(localChargeBytime.getAccountTimeCharge()))
				{
					throw new BaseException("50000-00001-00056");
				}
				if (Tools.isEmpty(localChargeBytime.getAttr2()))
				{
					throw new BaseException("50000-00001-00063");
				}
				if (Tools.isEmpty(localChargeBytime.getMaxCharge())
						&& Tools.isEmpty(localChargeBytime.getAccountTime()))
				{
					localChargeBytime.setAccountTime(null);
					localChargeBytime.setMaxCharge(null);
				}
				if (Tools.isEmpty(localChargeBytime.getSection())
						|| Tools.isEmpty(localChargeBytime.getType()))
				{
					localChargeBytime.setSection("2");
					localChargeBytime.setType("3");
				}
				if (!Tools.isEmpty(localChargeBytime.getAttr1()))
				{
					localChargeBytime.setAttr(localChargeBytime.getAttr1());
				}
				if (localChargeBytime.getSection().equalsIgnoreCase("1"))
				{
					if (Tools.isEmpty(localChargeBytime.getSectionStartTime()))
					{
						throw new BaseException("50000-00001-00058");
					}
					if (Tools.isEmpty(localChargeBytime.getSectionEndTime()))
					{
						throw new BaseException("50000-00001-00059");
					}
				}
				LocalWeekSection localWeekSection = new LocalWeekSection();
				if (!Tools.isEmpty(localChargeBytime.getWeekUuid()))
				{
					localWeekSection.setUuid(localChargeBytime.getWeekUuid());
					localWeekSection.setChargeBytimeUuid(localChargeBytime
							.getChargeBytimeUuid());
					localWeekSection
							.setCarTypeUuid(!Tools.isEmpty(localChargeBytime
									.getCarType()) ? localChargeBytime
									.getCarType() : null);
					localWeekSection
							.setSection(!Tools.isEmpty(localChargeBytime
									.getSection()) ? localChargeBytime
									.getSection() : "2");
					localWeekSection
							.setSectionEndTime(Tools.isEmpty(localChargeBytime
									.getSectionEndTime()) ? null
									: localChargeBytime.getSectionEndTime());
					localWeekSection
							.setSectionStartTime(!Tools
									.isEmpty(localChargeBytime
											.getSectionStartTime()) ? localChargeBytime
									.getSectionStartTime() : null);
					if (localChargeBytime.getSection().equalsIgnoreCase("2"))
					{
						localWeekSection.setSectionEndTime(null);
						localWeekSection.setSectionStartTime(null);
					}
					localWeekSection.setType(!Tools.isEmpty(localChargeBytime
							.getType()) ? localChargeBytime.getType() : null);
					localWeekSectionService
							.updateByPrimaryKey(localWeekSection);
				}
				localChargeBytimeMapper.updateByPrimaryKey(localChargeBytime);
				List<LocalChargeBytime> lis = localChargeBytimeMapper
						.queryRuleList();
				for (LocalChargeBytime ll : lis)
				{
					ll.setStatus(1);
					localChargeBytimeMapper.updateByPrimaryKey(ll);
				}
			}
		} catch (Throwable e)
		{
			throw new BaseException(e.getMessage());
		}
		return localChargeBytime.getChargeBytimeUuid();
	}
	
	@Override
	public void deletechargeBytime(List<String> ids)
	{
		// TODO Auto-generated method stub
		
		try
		{
			
			for (String id : ids)
			{
				localChargeBytimeMapper.deleteByPrimaryKey(id);
				localWeekSectionService.deleteWeekSection(id);
			}
		} catch (Throwable e)
		{
			throw new BaseException(e.getMessage(), e);
		}
	}
	
	@Override
	public List<LocalChargeBytime> queryRuleList()
	{
		// TODO Auto-generated method stub
		try
		{
			List<LocalChargeBytime> list = localChargeBytimeMapper
					.queryRuleList();
			if (!Tools.isEmpty(list) && list.size() > 0)
			{
				for (int i = 0; i < list.size(); i++)
				{
					LocalChargeBytime lb = list.get(i);
					lb.setCartypeName(localCarTypeMapper.selectCarNameByUuid(
							lb.getCarType()).getCartypeName());
					LocalWeekSection lws = localWeekSectionService
							.loadAllWeekSectionByChargUuid(lb
									.getChargeBytimeUuid());
					lb.setType(lws.getType());
					lb.setSection(lws.getSection());
					lb.setSectionStartTime(lws.getSectionStartTime());
					lb.setSectionEndTime(lws.getSectionEndTime());
				}
				return list;
			}
		} catch (Exception e)
		{
			// TODO: handle exception
			return null;
		}
		return null;
	}
	
	// 启用计费规则
	@Override
	public List<LocalChargeBytime> updateChargeBytime(List<String> ids,
			Integer status)
	{
		// TODO Auto-generated method stub
		List<LocalChargeBytime> aaa = new ArrayList<LocalChargeBytime>();
		try
		{
			String exchanuui = CloudConfigManager.instance().getCfgValueByKey(
					"exchange_id");
			if (status == 2)
			{
				if (returnRule(ids))
				{
					for (String id : ids)
					{
						LocalChargeBytime localChargeBytime = localChargeBytimeMapper
								.selectByPrimaryKey(id);
						localChargeBytime.setStatus(status);
						localChargeBytime.setParkOrgCode(exchanuui);
						localChargeBytimeMapper
								.updateByPrimaryKey(localChargeBytime);
						
						LocalWeekSectionExample condition = new LocalWeekSectionExample();
						condition.or().andChargeBytimeUuidEqualTo(
								localChargeBytime.getChargeBytimeUuid());
						LocalWeekSection lw = localWeekSectionService
								.selectByCondition(condition).get(0);
						if (!Tools.isEmpty(lw))
						{
							localChargeBytime.setWeekUuid(lw.getUuid());
							localChargeBytime.setSection(!Tools.isEmpty(lw
									.getSection()) ? lw.getSection() : "2");
							localChargeBytime.setSectionStartTime(!Tools
									.isEmpty(lw.getSectionStartTime()) ? lw
									.getSectionStartTime() : null);
							localChargeBytime.setSectionEndTime(!Tools
									.isEmpty(lw.getSectionEndTime()) ? lw
									.getSectionEndTime() : null);
							localChargeBytime.setType(!Tools.isEmpty(lw
									.getType()) ? lw.getType() : "3");
						}
						aaa.add(localChargeBytime);
					}
				} else
				{
					throw new BaseException("50000-00001-00060");
				}
			} else
			{
				List<LocalChargeBytime> lis = localChargeBytimeMapper
						.queryRuleList();
				for (LocalChargeBytime ll : lis)
				{
					ll.setStatus(status);
					ll.setParkOrgCode(exchanuui);
					localChargeBytimeMapper.updateByPrimaryKey(ll);
					
					LocalWeekSectionExample condition = new LocalWeekSectionExample();
					condition.or().andChargeBytimeUuidEqualTo(
							ll.getChargeBytimeUuid());
					LocalWeekSection lw = localWeekSectionService
							.selectByCondition(condition).get(0);
					if (!Tools.isEmpty(lw))
					{
						ll.setWeekUuid(lw.getUuid());
						ll.setSection(!Tools.isEmpty(lw.getSection()) ? lw
								.getSection() : "2");
						ll.setSectionStartTime(!Tools.isEmpty(lw
								.getSectionStartTime()) ? lw
								.getSectionStartTime() : null);
						ll.setSectionEndTime(!Tools.isEmpty(lw
								.getSectionEndTime()) ? lw.getSectionEndTime()
								: null);
						ll.setType(!Tools.isEmpty(lw.getType()) ? lw.getType()
								: "3");
					}
				}
				aaa = lis;
			}
		} catch (Exception e)
		{
			/* throw new BaseException(e.getMessage(), e); */
			return null;
		} finally
		{
			return aaa;
		}
	}
	
	// 封装LocalWeekSection分段信息，到计费规则里面
	public Boolean returnRule(List<String> ids)
	{
		try
		{
			List<LocalChargeBytime> list = new ArrayList<LocalChargeBytime>();
			List<LocalChargeBytime> lis = localChargeBytimeMapper
					.queryRuleList();
			for (String id : ids)
			{
				LocalChargeBytime localChargeBytime = localChargeBytimeMapper
						.selectByPrimaryKey(id);
				list.add(localChargeBytime);
			}
			
			for (String id : ids)
			{
				for (int i = 0; i < lis.size(); i++)
				{
					if (id.equalsIgnoreCase(lis.get(i).getChargeBytimeUuid()))
					{
						lis.remove(lis.get(i));
						i = i - 1;
					}
				}
			}
			for (LocalChargeBytime lb : lis)
			{
				list.add(lb);
			}
			
			for (int i = 0; i < list.size(); i++)
			{
				LocalChargeBytime lb = list.get(i);
				lb.setCartypeName(localCarTypeMapper.selectCarNameByUuid(
						lb.getCarType()).getCartypeName());
				LocalWeekSection lws = localWeekSectionService
						.loadAllWeekSectionByChargUuid(lb.getChargeBytimeUuid());
				lb.setType(lws.getType());
				lb.setSection(lws.getSection());
				lb.setSectionStartTime(lws.getSectionStartTime());
				lb.setSectionEndTime(lws.getSectionEndTime());
			}
			return compareRult(sortRule(list));
		} catch (Exception e)
		{
			// TODO: handle exception
			return false;
		}
	}
	
	// 根据分段开始时间，进行排序//从小到大
	public List<LocalChargeBytime> sortRule(List<LocalChargeBytime> li)
	{
		if (!Tools.isEmpty(li) && li.size() > 0)
		{
			// 根据开始时间 属性，进行排序
			Collections.sort(li, new Comparator<LocalChargeBytime>()
			{
				public int compare(LocalChargeBytime o1, LocalChargeBytime o2)
				{
					SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
					try
					{
						Date d1 = format.parse(o1.getSectionStartTime());
						Date d2 = format.parse(o2.getSectionStartTime());
						return d1.compareTo(d2);
					} catch (Exception e)
					{
						return 0;
					}
				}
			});
		}
		return li;
	}
	
	// 比较工作日，非工作日，不区分，分段，不分段规则，冲突则返回false
	public Boolean compareRult(List<LocalChargeBytime> li)
	{
		boolean falg = false;
		// 不区分
		List<LocalChargeBytime> listNo = new ArrayList<LocalChargeBytime>();
		// 工作日
		List<LocalChargeBytime> listWork = new ArrayList<LocalChargeBytime>();
		// 非工作日
		List<LocalChargeBytime> listNoWork = new ArrayList<LocalChargeBytime>();
		for (LocalChargeBytime lb : li)
		{
			if (lb.getType().equalsIgnoreCase("3"))
			{
				listNo.add(lb);
			}
			if (lb.getType().equalsIgnoreCase("2"))
			{
				listNoWork.add(lb);
			}
			if (lb.getType().equalsIgnoreCase("1"))
			{
				listWork.add(lb);
			}
		}
		try
		{
			// 无区分，无工作日 并且 无非工作日 则进入
			if (listNo.size() > 0 && listWork.size() <= 0
					&& listNoWork.size() <= 0)
			{
				falg = checkRule(listNo);
				if (falg == false)
				{
					return falg;
				}
			}
			// 有工作日,有非工作日.没有 无区分 则进入
			if (listWork.size() > 0 && listNoWork.size() > 0
					&& listNo.size() <= 0)
			{
				// 工作日计费规则 多条
				falg = checkRule(listWork);
				if (falg == false)
				{
					return falg;
				}
				// 非工作日多条
				falg = checkRule(listNoWork);
				if (falg == false)
				{
					return falg;
				}
			}
			return falg;
		} catch (Exception e)
		{
			// TODO: handle exception
			return false;
		}
	}
	
	public boolean checkRule(List<LocalChargeBytime> li)
	{
		boolean falg = false;
		if (li.size() > 1)
		{
			for (LocalChargeBytime liNo : li)
			{
				// 规则，如果没有分段收费.. 那么 li.size()>1 错误,返回false;
				// 1:分段收费 2:非分段收费
				if (liNo.getSection().equalsIgnoreCase("2"))
				{
					falg = false;
					return falg;
				} else
				{
					// 如果分段收费------进行fenduanRult分段判断
					falg = fenduanRult(li);
					if (falg == false)
					{
						return falg;
					} else
					{
						break;
					}
				}
			}
			if (falg == false)
			{
				return falg;
			}
		} else
		{
			// 只有一条规则，如果存在分段收费。返回:false
			if (li.get(0).getSection().equalsIgnoreCase("1"))
			{
				/* falg=fenduanRult(listNo); */
				falg = false;
				if (falg == false)
				{
					return falg;
				}
			} else
			{
				// 只有一条规则，不存在分段收费。返回:true
				falg = true;
			}
		}
		return falg;
	}
	
	// 比较分段时间,是否有重叠，如果重叠，则false
	public boolean fenduanRult(List<LocalChargeBytime> li)
	{
		boolean falg = true;
		try
		{
			SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
			for (int i = 0; i < li.size(); i++)
			{
				Date iStrat = format2.parse(li.get(i).getSectionStartTime());
				Date iEnd = format2.parse(li.get(i).getSectionEndTime());
				if (iStrat.getTime() == iEnd.getTime())
				{
					falg = false;
				}
				
				if (format2.parse(li.get(0).getSectionStartTime()).getTime() != -28800000)
				{
					falg = false;
				}
				if (format2.parse(li.get(li.size() - 1).getSectionEndTime())
						.getTime() != -28800000)
				{
					falg = false;
				}
				
				Date bStrat = format2.parse(li.get(
						i + 1 < li.size() ? i + 1 : 0).getSectionStartTime());
				if (bStrat.getTime() > iStrat.getTime()
						&& bStrat.getTime() < iEnd.getTime())
				{
					falg = false;
				}
			}
		} catch (Exception e)
		{
			// TODO: handle exception
			return false;
		}
		return falg;
	}
	
	public static void main(String[] args)
	{
		try
		{
			List<LocalChargeBytime> li = new ArrayList<LocalChargeBytime>();
			LocalChargeBytime lb = new LocalChargeBytime();
			lb.setType("1");// 1:工作日 2:非工作日 3:不区分
			lb.setSection("1");// 1分段收费 2非分段收费
			lb.setSectionStartTime("18:00:00");
			lb.setSectionEndTime("00:00:00");
			li.add(lb);
			LocalChargeBytime lb2 = new LocalChargeBytime();
			lb2.setType("1");// 1:工作日 2:非工作日 3:不区分
			lb2.setSection("1");// 1分段收费 2非分段收费
			lb2.setSectionStartTime("00:00:00");
			lb2.setSectionEndTime("12:00:00");
			li.add(lb2);
			LocalChargeBytime lb3 = new LocalChargeBytime();
			lb3.setType("1");// 1:工作日 2:非工作日 3:不区分
			lb3.setSection("1");// 1分段收费 2非分段收费
			lb3.setSectionStartTime("12:00:00");
			lb3.setSectionEndTime("18:00:00");
			li.add(lb3);
			if (!Tools.isEmpty(li) && li.size() > 0)
			{
				// 根据开始时间 属性，进行排序
				Collections.sort(li, new Comparator<LocalChargeBytime>()
				{
					public int compare(LocalChargeBytime o1,
							LocalChargeBytime o2)
					{
						SimpleDateFormat format = new SimpleDateFormat(
								"HH:mm:ss");
						try
						{
							Date d1 = format.parse(o1.getSectionStartTime());
							Date d2 = format.parse(o2.getSectionStartTime());
							return d1.compareTo(d2);
						} catch (Exception e)
						{
							return 0;
						}
					}
				});
				/*
				 * List<Date> startLs=new ArrayList<Date>(); List<Date>
				 * endLs=new ArrayList<Date>(); SimpleDateFormat format = new
				 * SimpleDateFormat("HH:mm:ss"); for(LocalChargeBytime lc:li){
				 * startLs.add(format.parse(lc.getSectionStartTime()));
				 * endLs.add(format.parse(lc.getSectionEndTime())); }
				 */
				for (LocalChargeBytime ll : li)
				{
					System.out.println("开始时间--" + ll.getSectionStartTime()
							+ "---结束时间--" + ll.getSectionEndTime());
				}
				boolean fadd = true;
				SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");
				for (int i = 0; i < li.size(); i++)
				{
					Date iStrat = format2
							.parse(li.get(i).getSectionStartTime());
					Date iEnd = format2.parse(li.get(i).getSectionEndTime());
					if (format2.parse(li.get(0).getSectionStartTime())
							.getTime() != -28800000)
					{
						fadd = false;
					}
					if (format2
							.parse(li.get(li.size() - 1).getSectionEndTime())
							.getTime() != -28800000)
					{
						fadd = false;
					}
					Date bStrat = format2.parse(li.get(
							i + 1 < li.size() ? i + 1 : 0)
							.getSectionStartTime());
					if (bStrat.getTime() > iStrat.getTime()
							&& bStrat.getTime() < iEnd.getTime())
					{
						fadd = false;
					}
				}
				System.out.println(fadd);
			}
		} catch (Exception e)
		{
			// TODO: handle exception
		}
	}
	
	@Override
	public LocalChargeBytime findByBrandId(String breandId)
	{
		LocalChargeBytimeExample ex = new LocalChargeBytimeExample();
		ex.or().andAttr4EqualTo(breandId);
		List<LocalChargeBytime> list = localChargeBytimeMapper
				.selectByCondition(ex);
		
		if (!Tools.isEmpty(list) && !list.isEmpty())
		{
			return list.get(0);
		}
		
		ex.or().andAttr4EqualTo("102");
		list = localChargeBytimeMapper.selectByCondition(ex);
		return list.isEmpty() ? null : list.get(0);
	}
}
